﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using PSE.ProcessManager.Entity.Enums;
using System.Reflection;

namespace ConfigurationManager.View.Dialog
{
    public partial class frmProcess : Form
    {
        Model.Process _process;
        List<Model.Product> _products;
        List<Model.Instance> _instances;
        List<Model.InteligenceModule> _inteligenceModules;

        public frmProcess(List<Model.Product> products, List<Model.Instance> instances, List<Model.InteligenceModule> inteligenceModules)
        {
            InitializeComponent();
            this.CenterToScreen();
            this.Text = "Inclusão de Processo";
            _products = products;
            _instances = instances;
            _inteligenceModules = inteligenceModules;

            LoadProductsCombo();
            LoadInteligenceModulesCombo();
            LoadFailureActionsCombo();
        }

        public frmProcess(List<Model.Product> products, List<Model.Instance> instances, List<Model.InteligenceModule> inteligenceModules, Model.Process process)
            : this(products, instances, inteligenceModules)
        {
            this.Text = "Edição de Processo";

            _process = process;

            txtCode.Text = _process.Id.ToString();
            cboProduct.Enabled = false;//nao pode alterar o produto pois e chave do processo           
            cboProduct.SelectedValue = _process.Instance.Product.Id;
            cboInstance.SelectedValue = _process.Instance.Id;
            txtName.Text = _process.Name;
            txtDescription.Text = _process.Description;
            cboInteligenceModule.SelectedValue = _process.InteligenceModule.Id;

            //InstanceContext 
            rdoSingle.Checked = _process.InstanceContext == PSE.ProcessManager.Entity.Enums.InstanceContext.Single;
            rdoMultiple.Checked = _process.InstanceContext == PSE.ProcessManager.Entity.Enums.InstanceContext.Multiple;

            txtAssembly.Text = _process.Assembly;
            txtClass.Text = _process.Class;
            cboFailureRecovery.SelectedValue = _process.FailureRecovery;

            //InitializationType
            rdoManual.Checked = _process.InitializationType == PSE.ProcessManager.Entity.Enums.StartUpType.Manual;
            rdoAutomatic.Checked = _process.InitializationType == PSE.ProcessManager.Entity.Enums.StartUpType.Automatic;

            rdoProcessEnabled.Checked = _process.IsActive;
            rdoProcessDisabled.Checked = !_process.IsActive;
        }

        private void LoadFailureActionsCombo()
        {
            List<KeyValuePair<FailureActions, string>> failureActions = new List<KeyValuePair<FailureActions, string>>();
            failureActions.Add(new KeyValuePair<FailureActions, string>(FailureActions.TakeNoAction, "Não fazer nada"));
            failureActions.Add(new KeyValuePair<FailureActions, string>(FailureActions.RestartProcess, "Reiniciar o processo"));

            cboFailureRecovery.DisplayMember = "Value";
            cboFailureRecovery.ValueMember = "Key";
            cboFailureRecovery.DataSource = failureActions;
        }


        private void LoadInteligenceModulesCombo()
        {
            _inteligenceModules.Insert(0, new ConfigurationManager.Model.InteligenceModule() { Id = -1, Name = null });

            cboInteligenceModule.DisplayMember = "Name";
            cboInteligenceModule.ValueMember = "Id";
            cboInteligenceModule.DataSource = _inteligenceModules;
        }

        private void LoadProductsCombo()
        {
            _products.Insert(0, new ConfigurationManager.Model.Product() { Id = -1, Name = null });

            cboProduct.DisplayMember = "Name";
            cboProduct.ValueMember = "Id";
            cboProduct.DataSource = _products;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                if (_process == null)
                    _process = new ConfigurationManager.Model.Process();

                _process.Instance.Product.Id = cboProduct.SelectedValue as int? ?? -1;
                _process.Instance.Id = cboInstance.SelectedValue as int? ?? -1;
                _process.Name = txtName.Text;
                _process.Description = txtDescription.Text;
                _process.InteligenceModule.Id = (int)cboInteligenceModule.SelectedValue;

                //InstanceContext 
                if (rdoSingle.Checked)
                    _process.InstanceContext = PSE.ProcessManager.Entity.Enums.InstanceContext.Single;
                if (rdoMultiple.Checked)
                    _process.InstanceContext = PSE.ProcessManager.Entity.Enums.InstanceContext.Multiple;

                _process.Assembly = txtAssembly.Text;
                _process.Class = txtClass.Text;

                _process.FailureRecovery = (FailureActions)cboFailureRecovery.SelectedValue;

                //InitializationType
                if (rdoManual.Checked)
                    _process.InitializationType = PSE.ProcessManager.Entity.Enums.StartUpType.Manual;
                else if (rdoAutomatic.Checked)
                    _process.InitializationType = PSE.ProcessManager.Entity.Enums.StartUpType.Automatic;

                _process.IsActive = rdoProcessEnabled.Checked;

                Model.Process.Save(_process);

                MessageBox.Show("Processo salvo com sucesso!", "Process Manager Configuration", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            catch (ValidationException ex)
            {
                MessageBox.Show(ex.Message, "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            catch (Exception ex)
            {
                //EventLog.WriteEntry("Process Manager - Configuration Manager", ex.ToString(), EventLogEntryType.Error);
                //MessageBox.Show("Ocorreu um erro interno, verifique o event viewer para maiores detalhes");
                Program.HandleException(ex);
            }
        }


        private void btnSearch_Click(object sender, EventArgs e)
        {
            DialogResult result;
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.DefaultExt = "dll";
            dialog.Filter = "Assemblies (*.dll)|*.dll";
            result = dialog.ShowDialog();
            if (result != DialogResult.Cancel)
            {
                txtAssembly.Text = dialog.FileName.Substring(dialog.FileName.LastIndexOf("\\") + 1, dialog.FileName.Length - (dialog.FileName.LastIndexOf("\\") + 1));
            }
        }

        private void cboProduct_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboProduct.SelectedIndex < 0)
                return;

            int productId = (int)cboProduct.SelectedValue;
            LoadInstanceCombo(productId);
        }

        private void LoadInstanceCombo(int productId)
        {
            //popular combo instancias
            List<Model.Instance> instances = _instances.FindAll(i => i.Product.Id == productId);

            instances.Insert(0, new ConfigurationManager.Model.Instance() { Id = -1, Name = null });

            cboInstance.DisplayMember = "Name";
            cboInstance.ValueMember = "Id";
            cboInstance.DataSource = instances;
        }

        private void rdoInicializacao_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoManual.Checked)
            {
                grbRecovery.Enabled = false;
            }
            else if (rdoAutomatic.Checked)
            {
                grbRecovery.Enabled = true;
            }

        }
    }
}
